#include"setgpio.h"

union gpioreg {
    struct
    {
        char em[0xc0];
        long gpiosel[4];
        long gpiodir[4];
        long gpioin[4];
        long gpioout[4];
        char em1[0xc0];
        long mux1[4];
        long mux2[4];
        long mux3[4];
        long mux4[4];
        long mux5[4];
    };
    char gpioreg[0xc0 + 64];
};

int fmm;
union gpioreg *mm;

void startmmap()
{
    fmm = open("/dev/mem", O_SYNC | O_RDWR);
    if (fmm <= 0)
    {
        printf("打开错误\n");
        return 1;
    }
    mm = (union gpioreg *)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, fmm, 0x1fd01000);
    if ((int)mm == -1 || (int)mm == 0)
    {
        printf("映射错误");
        return 1;
    }
    close(fmm);
   
}

void setiic(){
    int num = 0;
    num = 85;
    (*mm).mux1[num / 32] = ((1 << (num % 32))) | (*mm).mux1[num / 32];
    (*mm).mux2[num / 32] = (~(1 << (num % 32))) & (*mm).mux2[num / 32];
    (*mm).mux3[num / 32] = (~(1 << (num % 32))) & (*mm).mux3[num / 32];
    (*mm).mux4[num / 32] = (~(1 << (num % 32))) & (*mm).mux4[num / 32];
    (*mm).mux5[num / 32] = (~(1 << (num % 32))) & (*mm).mux5[num / 32];
    (*mm).gpiosel[num / 32] = (~(1 << (num % 32))) & (*mm).gpiosel[num / 32];
    (*mm).gpiodir[num / 32] = (~(1 << (num % 32))) & (*mm).gpiodir[num / 32];
    //(*mm).gpioout[num / 32] = (1 << (num % 32)) | (*mm).gpioout[num / 32];
    num = 86;
    (*mm).mux1[num / 32] = ((1 << (num % 32))) | (*mm).mux1[num / 32];
    (*mm).mux2[num / 32] = (~(1 << (num % 32))) & (*mm).mux2[num / 32];
    (*mm).mux3[num / 32] = (~(1 << (num % 32))) & (*mm).mux3[num / 32];
    (*mm).mux4[num / 32] = (~(1 << (num % 32))) & (*mm).mux4[num / 32];
    (*mm).mux5[num / 32] = (~(1 << (num % 32))) & (*mm).mux5[num / 32];
    (*mm).gpiosel[num / 32] = (~(1 << (num % 32))) & (*mm).gpiosel[num / 32];
    (*mm).gpiodir[num / 32] = (~(1 << (num % 32))) & (*mm).gpiodir[num / 32];
}

void setgpio(int num,char direc){//0输出，1输入
    if(num<0||num>127){
        return;
    }
    (*mm).mux1[num / 32] = (~(1 << (num % 32))) & (*mm).mux1[num / 32];
    (*mm).mux2[num / 32] = (~(1 << (num % 32))) & (*mm).mux2[num / 32];
    (*mm).mux3[num / 32] = (~(1 << (num % 32))) & (*mm).mux3[num / 32];
    (*mm).mux4[num / 32] = (~(1 << (num % 32))) & (*mm).mux4[num / 32];
    (*mm).mux5[num / 32] = (~(1 << (num % 32))) & (*mm).mux5[num / 32];
    (*mm).gpiosel[num / 32] = ((1 << (num % 32))) | (*mm).gpiosel[num / 32];
    if(direc){
        (*mm).gpiodir[num / 32] = ((1 << (num % 32))) | (*mm).gpiodir[num / 32];
    }
    else{
        (*mm).gpiodir[num / 32] = (~(1 << (num % 32))) & (*mm).gpiodir[num / 32];
    }
}


char readgpioval(int num){
    if (num < 0 || num > 127)
    {
        return;
    }
    if(((*mm).gpioin[num / 32]) & (1 << (num % 32))){
        return 1;
    }
    else{
        return 0;
    }
}

long readgpioval1(int ind){
    if (ind < 0 || ind > 3)
    {
        return;
    }
    return (*mm).gpioin[ind];
}

void setgpionum(int num, char val)
{
    if (num < 0 || num > 127)
    {
        return;
    }
    if (val)
    {
        (*mm).gpioout[num / 32] = (1 << (num % 32)) | (*mm).gpioout[num / 32];
    }
    else
    {
        (*mm).gpioout[num / 32] = (~(1 << (num % 32))) & (*mm).gpioout[num / 32];
    }
}

void setgpionum1(int ind, long val)
{
    if (ind < 0 || ind > 3)
    {
        return;
    }
    (*mm).gpioout[ind] = val;
}

void gpioummap(){
    munmap(mm, 0x1000);
}